package cate

import (
	"fmt"
	"net/http"
	model "server/model/article/cate"
	"server/utils"
	"strings"

	"github.com/gin-gonic/gin"
)

var tableName = "article_cate"

// CreateCate 创建分类
func CreateCate(c *gin.Context) {
	var req model.Cate
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	if !utils.ValidateStruct(c, &req) {
		return
	}
	if currentUserId, ok := c.Get("user_id"); ok {
		req.CreatorId = currentUserId.(int)
	} else {
		utils.JSONResponse(c, http.StatusUnauthorized, "身份验证失败！", nil)
		return
	}
	// 名称唯一性检查
	if exists, err := utils.CheckTableExist(tableName, "name", req.Name); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("创建分类失败: %v", err), nil)
		return
	} else if exists {
		utils.JSONResponse(c, http.StatusBadRequest, "分类已经存在", nil)
		return
	}
	if _, err := utils.DB.Exec(fmt.Sprintf("insert into %s (name,creator_id) values (?,?)", tableName), req.Name, req.CreatorId); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("创建分类失败: %v", err), nil)
		return
	}
	utils.JSONResponse(c, http.StatusOK, "创建分类成功", nil)
}

// UpdateCate 更新分类
func UpdateCate(c *gin.Context) {
	var req model.Cate
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	if !utils.ValidateStruct(c, &req) {
		return
	}
	if currentUserId, ok := c.Get("user_id"); ok {
		req.UpdaterId = currentUserId.(int)
	} else {
		utils.JSONResponse(c, http.StatusUnauthorized, "身份验证失败！", nil)
		return
	}
	// 是否存在
	if exists, err := utils.CheckTableExist(tableName, "id", req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("更新分类信息失败: %v", err), nil)
		return
	} else if !exists {
		utils.JSONResponse(c, http.StatusBadRequest, "分类不存在", nil)
		return
	}
	// 获取当前信息
	var info model.CateDetail
	if err := utils.DB.QueryRow(
		fmt.Sprintf("SELECT t.id, t.name, t.create_time, t.creator_id, '' as creator, t.update_time, t.updater_id, '' as updater FROM %s t WHERE t.id = ?", tableName),
		req.Id,
	).Scan(&info.Id, &info.Name, &info.CreateTime, &info.CreatorId, &info.Creator, &info.UpdateTime, &info.UpdaterId, &info.Updater); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("更新分类信息失败: %v", err), nil)
		return
	}
	if info.Name != req.Name {
		if exists, err := utils.CheckTableExist(tableName, "name", req.Name); err != nil {
			utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("更新分类信息失败: %v", err), nil)
			return
		} else if exists {
			utils.JSONResponse(c, http.StatusBadRequest, "分类已经存在", nil)
			return
		}
	}
	if _, err := utils.DB.Exec(fmt.Sprintf("update %s set name=?,updater_id=? where id=?", tableName), req.Name, req.UpdaterId, req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("更新分类信息失败: %v", err), nil)
		return
	}
	utils.JSONResponse(c, http.StatusOK, "更新分类信息成功", nil)
}

// DeleteCate 删除分类
func DeleteCate(c *gin.Context) {
	var req model.Cate
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	// 关联检查
	if exists, err := utils.CheckTableExist("article", "cate_id", req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("删除分类失败: %v", err), nil)
		return
	} else if exists {
		utils.JSONResponse(c, http.StatusBadRequest, "该分类下有文章，请先删除文章", nil)
		return
	}
	if _, err := utils.DB.Exec(fmt.Sprintf("delete from %s where id=?", tableName), req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("删除分类失败: %v", err), nil)
		return
	}
	utils.JSONResponse(c, http.StatusOK, "删除分类成功", nil)
}

// GetCateDetail 分类详情
func GetCateDetail(c *gin.Context) {
	var req model.Cate
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	sqlStr := fmt.Sprintf(`
		SELECT 
			t.id, 
			t.name, 
			t.create_time, 
			t.creator_id, 
			uc.username AS creator,
			t.update_time, 
			t.updater_id, 
			COALESCE(uu.username, '') AS updater
		FROM %s t
		LEFT JOIN user uc ON t.creator_id = uc.id
		LEFT JOIN user uu ON t.updater_id = uu.id
		WHERE t.id = ?
	`, tableName)
	var info model.CateDetail
	if err := utils.DB.QueryRow(sqlStr, req.Id).Scan(&info.Id, &info.Name, &info.CreateTime, &info.CreatorId, &info.Creator, &info.UpdateTime, &info.UpdaterId, &info.Updater); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("获取分类详情失败: %v", err), nil)
		return
	}
	utils.JSONResponse(c, http.StatusOK, "获取分类详情成功", info)
}

// GetCateList 分类列表
func GetCateList(c *gin.Context) {
	var req model.Query
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	var (
		args       []interface{}
		conditions []string
		result     = model.List{}
	)
	if req.Name != "" {
		conditions = append(conditions, "t.name LIKE ?")
		args = append(args, "%"+req.Name+"%")
	}
	countSQL := fmt.Sprintf("SELECT COUNT(*) FROM %s t WHERE 1=1", tableName)
	if len(conditions) > 0 {
		countSQL += " AND " + strings.Join(conditions, " AND ")
	}
	if err := utils.DB.QueryRow(countSQL, args...).Scan(&result.Total); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("获取分类列表失败: %v", err), nil)
		return
	}
	pageNum := 1
	pageSize := 100
	if req.PageNum != nil && *req.PageNum > 0 {
		pageNum = *req.PageNum
	}
	if req.PageSize != nil && *req.PageSize > 0 {
		pageSize = *req.PageSize
	}
	offset := (pageNum - 1) * pageSize
	querySQL := fmt.Sprintf(`
		SELECT 
			t.id, 
			t.name, 
			t.create_time, 
			t.creator_id, 
			uc.username AS creator,
			t.update_time, 
			t.updater_id, 
			COALESCE(uu.username, '') AS updater
		FROM %s t
		LEFT JOIN user uc ON t.creator_id = uc.id
		LEFT JOIN user uu ON t.updater_id = uu.id
		WHERE 1=1
	`, tableName)
	if len(conditions) > 0 {
		querySQL += " AND " + strings.Join(conditions, " AND ")
	}
	querySQL += " ORDER BY t.id DESC"
	querySQL += " LIMIT ? OFFSET ?"
	args = append(args, pageSize, offset)

	rows, err := utils.DB.Query(querySQL, args...)
	if err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("获取分类列表失败: %v", err), nil)
		return
	}
	defer rows.Close()

	var list []model.CateDetail
	for rows.Next() {
		var item model.CateDetail
		if err := rows.Scan(&item.Id, &item.Name, &item.CreateTime, &item.CreatorId, &item.Creator, &item.UpdateTime, &item.UpdaterId, &item.Updater); err != nil {
			utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("获取分类列表失败: %v", err), nil)
			return
		}
		list = append(list, item)
	}
	result.List = list
	utils.JSONResponse(c, http.StatusOK, "获取分类列表成功", result)
}


